<?php
/**
 * Created by PhpStorm.
 * User: chenyulingxi
 * Date: 2020/8/28
 * Time: 1:15
 */

namespace App\Repositories;

use App\Models\Order;
use App\Models\Topic;
use Illuminate\Support\Facades\DB;

class OrderRepository
{
    /**
     * @param $type
     * @param $id
     * @return array
     * @throws \App\Exceptions\HuanbaoException
     */
    public function checkout($type, $id)
    {
        $user = auth_user();
        $logPrefix = __METHOD__ . ", type: $type, id: $id";
        if ($type == Order::GOODS_TYPE_TOPIC) {
            $order = $user->orders()->goodsTypeIsTopic($id)->first();
            if ($order) {
                $msg = "帖子: $id 已经购买";
                logger("$logPrefix, $msg, order: " . json_encode_unicode($order->toArray()));
                logic_abort($msg);
            }
            $topic = Topic::query()->findOrFail($id);
            $comment = $topic->mainFloor;
            $hide = $comment->hide;
            if (!$hide) {
                logic_abort("帖子： $id 没有隐藏内容");
            }
            if ($hide->require_score <= 0) {
                logic_abort("帖子： $id 不需要积分购买");
            }
            if ($user->score_count < $hide->require_score) {
                logic_abort("你的积分：{$user->score_count} 不足以购买此帖子，需要：{$hide->require_score}");
            }
            $msg = sprintf('你当前拥有积分：%s, 确定使用 %s 积分购买此帖子的隐藏内容吗?', $user->score_count, $hide->require_score);
            return api(RET_OK, $msg, ['topic' => $topic, 'hide' => $hide]);
        }

        logic_abort("不支持此类型：$type");
    }

    /**
     * 创建积分购买帖子订单
     *
     * @param $tid
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
     * @throws \App\Exceptions\HuanbaoException
     */
    public function createGoodsTypeTopicOrder($tid)
    {
        $goodsType = Order::GOODS_TYPE_TOPIC;
        $checkoutResult = $this->checkout($goodsType, $tid);
        $topic = $checkoutResult['data']['topic'];
        $hide = $checkoutResult['data']['hide'];
        $user = auth_user();
        $insert = [
            'uid' => $user->id,
            'goods_type' => $goodsType,
            'goods_id' => $tid,
            'price' => $hide->require_score,
            'status' => Order::STATUS_INIT,
            'snapshot' => json_encode_unicode(['topic' => $topic->toArray(), 'hide' => $hide->toArray()]),
        ];
        $order = Order::query()->create($insert);
        return $order;
    }

    /**
     * 使用用户积分进行支付
     *
     * @param Order $order
     * @return Order|mixed
     * @throws \App\Exceptions\HuanbaoException
     */
    public function payByScore(Order $order)
    {
        $user = $order->user;
        if ($user->score_count < $order->price) {
            logic_abort(sprintf(
                '用户 %s 积分 %s 不足以支付订单所需 %s',
                $user->id, $user->score_count, $order->price
            ));
        }
        $order = DB::transaction(function () use ($user, $order) {
            $logPrefix = sprintf('%s, user: %s, order: %s', __METHOD__, $user->id, $order->id);
            $update = [
                'status' =>  Order::STATUS_PAY_SUCCESS,
                'paid_at' => now()->toDateTimeString(),
                'pay_type' => Order::PAY_TYPE_SCORE,
            ];
            $affectedRows = DB::table($order->getTable())
                ->where('id', $order->id)
                ->where('status', Order::STATUS_INIT)
                ->whereNull('paid_at')
                ->update($update);
            if ($affectedRows != 1) {
                $msg = "订单更新失败";
                logger("$logPrefix, $msg, sql: " . last_query());
                logic_abort($msg);
            }

            $update = [
                'score_count' => $user->score_count - $order->price,
            ];
            $affectedRows = DB::table($user->getTable())
                ->where('id', $user->id)
                ->where('score_count', $user->score_count)
                ->update($update);
            if ($affectedRows != 1) {
                $msg = "用户更新失败";
                logger("$logPrefix, $msg, sql: " . last_query());
                logic_abort($msg);
            }
            logger("$logPrefix, 支付成功");
            return $order;

        });

        return $order;
    }
}